package com.sinothk.fc.attend.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sinothk.fc.attend.entity.*;
import com.sinothk.fc.attend.mapper.AttendConfigMapper;
import com.sinothk.fc.attend.mapper.AttendRecordMapper;
import com.sinothk.fc.attend.service.IAttendConfigService;
import com.sinothk.fc.attend.service.IAttendRecordService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.UnitUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @Description: 考勤记录表
 * @Author: Liangyt
 * @Date: 2022-09-18
 * @Version: V1.0
 */
@Service
public class AttendRecordServiceImpl extends ServiceImpl<AttendRecordMapper, AttendRecordEntity> implements IAttendRecordService {
    @Resource
    private AttendConfigMapper attendConfigMapper;
    private final IAttendConfigService attendConfigService;
    @Resource
    private AttendRecordMapper attendRecordMapper;

    public AttendRecordServiceImpl(IAttendConfigService attendConfigService) {
        this.attendConfigService = attendConfigService;
    }

    @Override
    public AttendConfigAndTodayDataBean getAttendConfigAndTodayData() throws Exception {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (StringUtils.isBlank(loginUser.getStoreId())) throw new Exception("用户不属于任何门店");

        String storeId = loginUser.getStoreId();
        // 考勤配置
        LambdaQueryWrapper<AttendConfigEntity> wrapperForAttendConfig = new LambdaQueryWrapper<>();
        wrapperForAttendConfig.eq(AttendConfigEntity::getStoreId, storeId);
        AttendConfigEntity attendConfig = attendConfigService.getOne(wrapperForAttendConfig);
        // 今天的考勤信息
        Date today = new Date();
        String thisMonth = DateUtil.format(today, "yyyy年MM月");
        String thisDay = DateUtil.format(today, "yyyy年MM月dd日");
        LambdaQueryWrapper<AttendRecordEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttendRecordEntity::getAttendMonth, thisMonth)
                .eq(AttendRecordEntity::getAttendDay, thisDay)
                .eq(AttendRecordEntity::getStoreId, loginUser.getStoreId())
                .eq(AttendRecordEntity::getEmployeeId, loginUser.getId());
        AttendRecordEntity attendRecord = this.getOne(wrapper);

        AttendConfigAndTodayDataBean attendConfigAndTodayDataBean = new AttendConfigAndTodayDataBean();
        attendConfigAndTodayDataBean.setAttendConfig(attendConfig);
        attendConfigAndTodayDataBean.setAttendRecord(attendRecord);
        return attendConfigAndTodayDataBean;
    }

    @Override
    public void addOrEdit(AttendRecordReq recordReq) throws Exception {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (StringUtils.isBlank(loginUser.getStoreId())) throw new Exception("用户不属于任何门店");

        LambdaQueryWrapper<AttendConfigEntity> wrapperForConfig = new LambdaQueryWrapper<>();
        wrapperForConfig.eq(AttendConfigEntity::getStoreId, loginUser.getStoreId());
        AttendConfigEntity attendConfig = attendConfigMapper.selectOne(wrapperForConfig);

        AttendRecordEntity attendRecord = new AttendRecordEntity();
        attendRecord.setStoreId(loginUser.getStoreId());
        attendRecord.setEmployeeId(loginUser.getId());
        Date today = new Date();
        attendRecord.setAttendMonth(DateUtil.format(today, "yyyy年MM月"));
        attendRecord.setAttendDay(DateUtil.format(today, "yyyy年MM月dd日"));

        LambdaQueryWrapper<AttendRecordEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttendRecordEntity::getAttendMonth, attendRecord.getAttendMonth())
                .eq(AttendRecordEntity::getAttendDay, attendRecord.getAttendDay())
                .eq(AttendRecordEntity::getStoreId, attendRecord.getStoreId())
                .eq(AttendRecordEntity::getEmployeeId, attendRecord.getEmployeeId());
        List<AttendRecordEntity> list = this.list(wrapper);

        if (list != null && list.size() > 1) {
            throw new Exception("你的考勤记录一天内有多条");
        } else {
            int time = Integer.parseInt(DateUtil.format(new Date(), "HHmm"));

            if (list != null && list.size() == 1) { // 签退可以更新
                if (recordReq.getAttendLevel() == 1) {
                    attendRecord.setAttendExitFileUrl(recordReq.getAttendFileUrl());
                    attendRecord.setAttendExitLat(recordReq.getAttendLat());
                    attendRecord.setAttendExitLng(recordReq.getAttendLng());
                    attendRecord.setAttendExitAddress(recordReq.getAttendAddress());
                    attendRecord.setAttendExitTime(time);

                    dealData(attendConfig, attendRecord, 1);

                    AttendRecordEntity attendRecordDB = list.get(0);
                    attendRecord.setId(attendRecordDB.getId());
                    this.updateById(attendRecord);
                } else {
                    throw new Exception("已经签退，不能再签到");
                }
            } else {
                attendRecord.setEmployeeName(loginUser.getRealname());
                if (recordReq.getAttendLevel() == 0) {
                    attendRecord.setAttendEnterFileUrl(recordReq.getAttendFileUrl());
                    attendRecord.setAttendEnterLat(recordReq.getAttendLat());
                    attendRecord.setAttendEnterLng(recordReq.getAttendLng());
                    attendRecord.setAttendEnterAddress(recordReq.getAttendAddress());
                    attendRecord.setAttendEnterTime(time);

                    dealData(attendConfig, attendRecord, 0);

                } else if (recordReq.getAttendLevel() == 1) {
                    attendRecord.setAttendExitFileUrl(recordReq.getAttendFileUrl());
                    attendRecord.setAttendExitLat(recordReq.getAttendLat());
                    attendRecord.setAttendExitLng(recordReq.getAttendLng());
                    attendRecord.setAttendExitAddress(recordReq.getAttendAddress());
                    attendRecord.setAttendExitTime(time);
                    dealData(attendConfig, attendRecord, 1);
                } else {
                    throw new Exception("考勤类型只能为0或1");
                }
                // 设置配置信息
                attendRecord.setConfigAddress(attendConfig.getConfigAddress());
                attendRecord.setConfigDistance(attendConfig.getConfigDistance());
                attendRecord.setConfigEnterTime(attendConfig.getEnterTime());
                attendRecord.setConfigExitTime(attendConfig.getExitTime());
                attendRecord.setConfigLat(attendConfig.getConfigLat());
                attendRecord.setConfigLng(attendConfig.getConfigLng());
                this.save(attendRecord);
            }
        }
    }

    private void dealData(AttendConfigEntity attendConfig, AttendRecordEntity attendRecord, int level) {
        if (level == 0) {// 签到
            if (attendConfig.getEnterTime() >= attendRecord.getAttendEnterTime()) {
                attendRecord.setAttendEnterState(0);//考勤状态：0正常1迟到2请假3缺卡4早退5旷工
            } else {
                attendRecord.setAttendEnterState(1); // 迟到
            }
            attendRecord.setAttendEnterDistance(UnitUtil.calculate2PointDistance(attendConfig.getConfigLat(), attendConfig.getConfigLng(),
                    attendRecord.getAttendEnterLat(), attendRecord.getAttendEnterLng()));
        } else { // 签退
            if (attendConfig.getExitTime() <= attendRecord.getAttendExitTime()) {
                attendRecord.setAttendExitState(0);//考勤状态：0正常1迟到2请假3缺卡4早退5旷工
            } else {
                attendRecord.setAttendExitState(4); // 4早退
            }
            attendRecord.setAttendExitDistance(UnitUtil.calculate2PointDistance(attendConfig.getConfigLat(), attendConfig.getConfigLng(),
                    attendRecord.getAttendExitLat(), attendRecord.getAttendExitLng()));
        }
    }

    @Override
    public StatisticsAttendForEmployeeBean statisticsForCurrUser() throws Exception {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (StringUtils.isBlank(loginUser.getStoreId())) throw new Exception("用户不属于任何门店");
        return attendRecordMapper.statisticsMonthForCurrUser(loginUser.getStoreId(), loginUser.getId());
    }

    @Override
    public StatisticsAttendForEmployeeBean statisticsForEmployee() throws Exception {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (StringUtils.isBlank(loginUser.getStoreId())) throw new Exception("用户不属于任何门店");
        return attendRecordMapper.statisticsForEmployee(loginUser.getStoreId());
    }
}
